package tests;

import static org.junit.Assert.*;


import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import model.Email;
import model.EmailBuilder;
import model.FilterBuilder;
import model.Folder;
import model.User;
import model.Filter;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * This class tests the User filters functionality
 * 
 * @author Sukhjinder K. Narula
 * @since June 2013
 *
 * @version $Revision: 1.0 $
 */
public class TestUserFilters {

	User user;
	HashMap<String, String> properties;
	List<Filter> filters;
	Filter filter1, filter2;
	Date date;
	int uid=-1;
	Timestamp currentTime;
	EmailBuilder emb=new EmailBuilder();
	Email em;
	
	/**
	 * This method is called before every test case, it creates a new user, sets its properties and adds two filters to its
	 * list of filters.
	 */
	@Before
	public void setUp()
	{
		 date= new Date();
		 currentTime=(new Timestamp(date.getTime()));
		 em=emb.setTo("musab").setFrom("skanrula").setSubject("filter 1").setBody("testing filters")
				 .setRead(false).setTimestamp(currentTime).setFolderId(1).build();
		 
		user=new User("sknarula");
		properties=new HashMap<String,String>();
		properties.put("Id", "1");
		properties.put("Name","Laura");
		Folder folder1, folder2;
		folder1=new Folder("New parent folder",1,0);
		folder1.setId(1);
		folder2=new Folder("New child folder",1,1);
		folder2.setId(2);
		
		filter1 = new FilterBuilder().setUserId(1).setTitle("Filter 1").setSubject("filter 1").setTo("musab").setFrom("skanrula").setBody("testing filters").setFolderId(1).build();
		filter1.setId(1);
		filter2 = new FilterBuilder().setUserId(1).setTitle("Filter 2").setSubject("filter 2").setTo("buthainah").setFrom("skanrula").setBody("testing filters").setFolderId(2).build();
		filter2.setId(2);
		filters = new ArrayList<Filter>();
		filters.add(filter1);
		filters.add(filter2);
		
		user.setFilters(filters);		
	}
	
	/**
	 * This method is called after every test case to tear down the user object and force garbage collection.
	 */
	@After
	public void tearDown()
	{
		user=null;
		System.gc();
	}
	
	/**
	 * This test ensures that given an id, the get filter method returns the correct object
	 */
	@Test
	public void testGetFilterById() {
		Filter result = user.getFilter(1);
		assertEquals(result, filter1);
	}
	
	/**
	 * This test ensures that given an key, the get filter method returns the correct object
	 */
	@Test
	public void testGetFilterByTitle() {
		Filter result = user.getFilter("Filter 2");
		assertEquals(result, filter2);
	}
	
	/**
	 * This test case tests the getFilters method by ensuring that the size of the list of filters equals to the one specified.
	 */
	@Test
	public void testGetFiltersBySize() {
		List<Filter> result=user.getFilters();
		assertEquals(2,result.size());
	}

	/**
	 * This test ensures that transfer object for filter is created appropriately
	 */
	@Test
	public void testGetTransferObjectToGetFilterHashMap() {
		@SuppressWarnings("serial")

		HashMap<String, String> filterTransferObject = new HashMap<String, String>(){{
			put("Id", String.valueOf(1));
			put("UserId", String.valueOf(1));
			put("Title", "Filter 1");
			put("Subject","filter 1");
			put("ToEmail", "musab");
			put("FromEmail", "skanrula");
			put("Body", "testing filters");
			put("FolderId", String.valueOf(1));
		}};
		
		
		assertEquals(filterTransferObject, filter1.getTransferObject());		
	}
	
	/**
	 * This test ensures that transfer object is created appropriately
	 */
	@Test
	public void testGetTransferObjectToGetEmptyHashMap() {
		HashMap<String, String> meetingTransferObject = new HashMap<String, String>();
		assertFalse(meetingTransferObject.equals(filter1.getTransferObject()));
	}
	
	/**
	 * This test case tests the getFilters method by ensuring that the list of the filters return is equals to whats setup
	 */
	@Test
	public void testGetFiltersByData() {
		List<Filter> result=user.getFilters();
		assertEquals(result,filters);
	}
	/**
	 * This test case tests the getUserId method
	 */
	@Test
	public void testGetUserId()
	{
		assertEquals(1,filter1.getUserId());
	}
	
	/**
	 * This test case tests the getTo method
	 */
	@Test
	public void testGetTo()
	{
		assertEquals("musab",filter1.getTo());
	}
	
	/**
	 * This test case tests the getFrom method
	 */
	@Test
	public void testGetFrom()
	{
		assertEquals("skanrula",filter1.getFrom());
	}
	

	/**
	 * This test case tests the getBody method
	 */
	@Test
	public void testGetBody()
	{
		assertEquals("testing filters",filter1.getBody());
	}
	
	/**
	 * This test case tests the getFolderId method
	 */
	@Test
	public void testGetFolderId()
	{
		assertEquals(1,filter1.getFolderId());
	}
	
	/**
	 * This test case tests the setUserId method
	 */
	@Test
	public void testSetUserId()
	{
		filter1.setUserId(2);
		assertEquals(2,filter1.getUserId());
	}
	
	/**
	 * This test case tests the setTitle method
	 */
	@Test
	public void testSetTitle()
	{
		filter1.setTitle("new title");
		assertEquals("new title",filter1.getTitle());
	}
	
	/**
	 * This test case tests the setTo method
	 */
	@Test
	public void testSetTo()
	{
		filter1.setTo("new to");
		assertEquals("new to",filter1.getTo());
	}
	
	/**
	 * This test case tests the setFrom method
	 */
	@Test
	public void testSetFrom()
	{
		filter1.setFrom("new from");
		assertEquals("new from",filter1.getFrom());
	}
	
	/**
	 * This test case tests the setBody method
	 */
	@Test
	public void testSetBody()
	{
		filter1.setBody("new body");
		assertEquals("new body",filter1.getBody());
	}
	
	/**
	 * This test case tests the setFolderId method
	 */
	@Test
	public void testSetFolderId()
	{
		filter1.setFolderId(2);
		assertEquals(2,filter1.getFolderId());
	}
	
	/**
	 * This test case tests the getTransferObject method
	 */
	@Test
	public void testGetTransferObject()
	{
		HashMap<String, String> result = new HashMap<String, String>();
		result=filter1.getTransferObject();
		assertEquals(8,result.size());
		assertNotNull(result);
	}
	
	/**
	 * This test case tests the getWeight method
	 */
	@Test
	public void testGetWeight()
	{
		assertEquals(6,filter1.getWeight());
	}
	
	/**
	 * This test case tests the filterApplies method
	 */
	@Test
	public void testFilterApplies()
	{
		assertTrue(filter1.filterApplies(em));
		assertFalse(filter2.filterApplies(em));
	}

}
